/*--------------------------------------------------------------------------------*/
#ifndef __INTERFACE_MENU__
#define __INTERFACE_MENU__
/*--------------------------------------------------------------------------------*/
#include "primitives.h"
#include "interface_container.h"
#include "util.h"
#include "input_system.h"
#include "input_key.h"
#include "component_state_chart.h"
/*--------------------------------------------------------------------------------*/
class INTERFACE_MENU : public INTERFACE_CONTAINER
{

	// -- PUBLIC

public:

    DECLARE_REF( INTERFACE_MENU );
    
    // .. TYPES
    
    enum EVENT
    {
    	EVENT_OnItemActivated,
    	EVENT_Count
    };
    
    struct EVENT_INFO
    {
    	INDEX 
    		StateChartEvent;
    	COMPONENT_STATE_CHART
    		*StateChart;	
    		
    	EVENT_INFO()
    	{
    		StateChart = NULL;
    	}	
    };

    // .. CONSTRUCTORS

    INTERFACE_MENU() :
    	INTERFACE_CONTAINER(),
    	SelectedItemIndex( 0 )
    {

    }

    ~INTERFACE_MENU()
    {
     
    }

    // .. METHODS

    virtual VOID Update( const TIMER & timer )
    {
    	INTERFACE_CONTAINER::Update( timer );
    	
    	if( INPUT_SYSTEM::GetInstance().IsKeyJustPressed( INPUT_KEY_Up ) )
    	{
    		SelectPreviousItem();
    		ApplySelection();
    	}
    	else if( INPUT_SYSTEM::GetInstance().IsKeyJustPressed( INPUT_KEY_Down ) )
    	{
    		SelectNextItem();
    		ApplySelection();
      	}
      	else if( INPUT_SYSTEM::GetInstance().IsKeyJustPressed( INPUT_KEY_Return ) )
      	{
      		if( EventInfoTable[ EVENT_OnItemActivated ].StateChart )
      		{
      			EventInfoTable[ EVENT_OnItemActivated ].StateChart->LaunchEvent( 
      				EventInfoTable[ EVENT_OnItemActivated ].StateChartEvent ,
      				REF_TO_< OBJECT >( ObjectTable[ SelectedItemIndex ] ) 				
      				);
      		}
      	}   	
    }
    
    VOID SelectNextItem()
    {    
    	if( ++SelectedItemIndex  >= ObjectTable.GetItemCount() )
    	{
    		SelectedItemIndex %= ObjectTable.GetItemCount();
    	}    	
    }
    
    VOID SelectPreviousItem()
    {
    	if( !SelectedItemIndex )
    	{
    		SelectedItemIndex = ObjectTable.GetItemCount() - 1;
    	}
    	else
    	{
    		--SelectedItemIndex;
    	}    
    }
    

    VOID SelectItem( const INDEX item_index )
    {
    	DEBUG_Require( item_index < ObjectTable.GetItemCount() );

    	SelectedItemIndex = item_index;
    	ApplySelection();
    }

    VOID ApplySelection()
    {
    	INDEX
    		index;
    		
		for_each_table_index( index, ObjectTable )
		{
			if( ObjectTable[ index ]->IsSelected() && index != SelectedItemIndex )
			{
				ObjectTable[ index ]->Unselect();
			}
			else if( !ObjectTable[ index ]->IsSelected() && index == SelectedItemIndex )
			{
				ObjectTable[ index ]->Select();	
			}
		}
    }
    	
    VOID BindEvent( const EVENT event, COMPONENT_STATE_CHART * state_chart, const INDEX state_chart_event )
    {
    	EVENT_INFO
    		info;
    		
    	info.StateChartEvent = state_chart_event;
    	info.StateChart = state_chart;
    	
    	EventInfoTable[ event ] = info;
    }
    
    INDEX GetSelectedItemIndex() const
    {
    	return SelectedItemIndex;
    }

    // -- PROTECTED

protected :

	INDEX
		SelectedItemIndex;
	TABLE< EVENT_INFO, EVENT_Count >
		EventInfoTable;

    
};
/*--------------------------------------------------------------------------------*/
#endif
